/*
 *
 * Copyright (C) 2012 Walter Lütgenau
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 */
package offset.nodes.client.dialog.setup.view;

import java.awt.Color;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;
import offset.nodes.Constants;
import offset.nodes.client.chooser.view.NodeRendererFactory;
import offset.nodes.client.model.ActivePanelContainer;
import offset.nodes.client.model.Initializable;
import offset.nodes.client.dialog.newnode.model.ObjectType;
import offset.nodes.client.dialog.newnode.model.SetupModel;

/**
 *
 * @author  Walter Lütgenau
 */
public class SelectObjectTypePanel extends javax.swing.JPanel implements Initializable {
    SetupModel model;
    ActivePanelContainer container;
    
    /** Creates new form SelectObjectTypePanel */
    public SelectObjectTypePanel(SetupModel model) {
        initComponents();
        this.model = model;
        
        model.setCurrentObjectType(0);
        
        DefaultMutableTreeNode root = createObjectTree(model);
        objectTree.setModel(new DefaultTreeModel(root));
        
        objectTree.addTreeSelectionListener(new TreeSelectionListener() {
            public void valueChanged( TreeSelectionEvent e) {
                if ( objectTree.getSelectionCount() != 1)
                    return;
                TreePath path = objectTree.getSelectionPath();
                DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent();

                if (!(node.getUserObject() instanceof ObjectWrapper))
                    return;

                ObjectType type = (ObjectType) ((ObjectWrapper)node.getUserObject()).getType();
                
                descriptionPane.setText(type.getDescription());
                
                int i=0;
                while( i<getModel().getObjectTypes().length) {
                    if ( getModel().getObjectTypes()[i] == type )
                        break;
                    i++;
                }
                
                getModel().setCurrentObjectType(i);
                getModel().setCurrentStep(0);
            }
        });

        MouseListener ml = new MouseAdapter() {

            public void mousePressed(MouseEvent e) {
                int selRow = objectTree.getRowForLocation(e.getX(), e.getY());
                TreePath selPath = objectTree.getPathForLocation(e.getX(), e.getY());
                if (selRow != -1)
                    if (e.getClickCount() == 2)
                        container.executeOk();
            }
        };
        objectTree.addMouseListener(ml);
    }

    @Override
    public void init(ActivePanelContainer container) {
        this.container = container;
    }
    
    public SetupModel getModel() {
        return model;
    }
    
    class ObjectWrapper {
        private ObjectType type;
        
        public ObjectWrapper(ObjectType type) {
            this.setType(type);
        }
        
        public String toString() {
            return getLastPathComponent(getType().getName());
        }

        public ObjectType getType() {
            return type;
        }

        public void setType(ObjectType type) {
            this.type = type;
        }

        protected String getLastPathComponent(String path) {
            int last = path.lastIndexOf(Constants.PATH_SEPARATOR);
            if (last < 0)
                return path;

            return path.substring(last + 1);
        }
    }
    
    protected DefaultMutableTreeNode createObjectTree(SetupModel model) {
        DefaultMutableTreeNode root = new DefaultMutableTreeNode();
        
        for( int i=0; i<model.getObjectTypes().length; i++) {
            ObjectType type = model.getObjectTypes()[i];
            
            DefaultMutableTreeNode node = new DefaultMutableTreeNode(new ObjectWrapper(type));
            addNode(root, type.getName(), node);
        }
        
        return root;
    }

    /**
     * Add a node to the tree.
     *
     * If the node path contains separators, find the parent nodes. If they do not yet exist,
     * create them.
     * 
     * @param root
     * @param path
     * @param child
     */
    protected void addNode(DefaultMutableTreeNode root, String path, DefaultMutableTreeNode child) {
        String[] dirs = path.split(Constants.PATH_SEPARATOR);
        if (dirs.length == 1) {
            root.add(child);
            return;
        }

        boolean found = false;
        for (int i = 0; i < dirs.length - 1; i++) {
            found = false;

            for (int j = 0; j < root.getChildCount(); j++) {
                if (dirs[i].equals(root.getChildAt(j).toString())) {
                    root = (DefaultMutableTreeNode) root.getChildAt(j);
                    found = true;
                    break;
                }
            }

            if (!found) {
                DefaultMutableTreeNode branch = new DefaultMutableTreeNode(dirs[i]);
                root.add(branch);
                root = branch;
            }
        }

        root.add(child);
    }
    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        objectTree = new javax.swing.JTree();
        descriptionPane = new javax.swing.JEditorPane();

        setPreferredSize(new java.awt.Dimension(100, 100));

        objectTree.setBorder(javax.swing.BorderFactory.createEmptyBorder(3, 3, 1, 1));
        objectTree.setCellRenderer(NodeRendererFactory.createNodeRenderer());
        jScrollPane1.setViewportView(objectTree);

        descriptionPane.setBackground(new Color(0,0,0,0));
        descriptionPane.setFont(descriptionPane.getFont());
        descriptionPane.setMargin(new java.awt.Insets(3, 0, 3, 3));
        descriptionPane.setOpaque(false);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane1)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(descriptionPane)
                        .addContainerGap())))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(21, 21, 21)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 233, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addComponent(descriptionPane, javax.swing.GroupLayout.PREFERRED_SIZE, 128, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        descriptionPane.getAccessibleContext().setAccessibleDescription("text/html");
    }// </editor-fold>//GEN-END:initComponents
    
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JEditorPane descriptionPane;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTree objectTree;
    // End of variables declaration//GEN-END:variables
    
}
